#include <rclcpp/rclcpp.hpp>

class singleClock {
public:
  singleClock() {}
  ~singleClock() = default;

  void setClock(const rclcpp::Clock::SharedPtr &clock) {
    steady_clock_ = clock;
  }
  rclcpp::Clock::SharedPtr getClock() { return steady_clock_; }
  void throttle(rclcpp::Logger logger, rclcpp::Clock clock, int duration,
                const std::string &format, const std::string &arg) {
    RCLCPP_INFO_THROTTLE(logger, clock, duration, format.c_str(), arg.c_str());
  }

private:
  rclcpp::Clock::SharedPtr steady_clock_;
  // rclcpp::Logger logger_;
};

class NodeLog : public rclcpp::Node {
public:
  NodeLog(std::string name) : Node(name) {
    RCLCPP_INFO(this->get_logger(), "This is info log...");
    single_clcok_.push_back(std::make_shared<singleClock>());
    single_clcok_.push_back(std::make_shared<singleClock>());
    single_clcok_.push_back(std::make_shared<singleClock>());
    single_clcok_[0]->setClock(std::make_shared<rclcpp::Clock>());
    single_clcok_[1]->setClock(std::make_shared<rclcpp::Clock>());
    single_clcok_[2]->setClock(std::make_shared<rclcpp::Clock>());
  }

  void timer_out() {
    while (1) {
      // for (size_t i = 0; i < 3; ++i)
      // {
      // RCLCPP_INFO_THROTTLE(single_clcok_[i]->get_logger(),
      // *(single_clcok_[i]->getClock()), 5000, "clock %d print info ...",
      // static_cast<int>(i)); RCLCPP_INFO_THROTTLE(rclcpp::get_logger("1"),
      // *(single_clcok_[0]->getClock()), 1000, "clock %d print info ...", 1);
      // RCLCPP_INFO_THROTTLE(rclcpp::get_logger("2"),
      // *(single_clcok_[1]->getClock()), 2000, "clock %d print info ...", 2);
      // RCLCPP_INFO_THROTTLE(rclcpp::get_logger("3"),
      // *(single_clcok_[2]->getClock()), 3000, "clock %d print info ...", 3);
      // }
      // RCLCPP_INFO_THROTTLE(this->get_logger(), *this->get_clock(), 10000,
      // "clock %d print info ...", 1); RCLCPP_INFO_THROTTLE(this->get_logger(),
      // *this->get_clock(), 5000, "clock %d print info ...", 2);
      // RCLCPP_INFO_THROTTLE(this->get_logger(), *this->get_clock(), 1000,
      // "clock %d print info ...", 3);
      for (size_t i = 0; i < 3; ++i) {
        // single_clcok_[i]->throttle(this->get_logger(), *this->get_clock(),
        // 10000, "clock %s print info ...", std::to_string(i));
        if (i == 0) {
          single_clcok_[i]->throttle(this->get_logger(), *this->get_clock(),
                                     10000, "clock %s print info ...",
                                     std::to_string(i));
        } else if (i == 1) {
          single_clcok_[i]->throttle(this->get_logger(), *this->get_clock(),
                                     10000, "clock %s print info ...",
                                     std::to_string(i));
        } else {
          single_clcok_[i]->throttle(this->get_logger(), *this->get_clock(),
                                     10000, "clock %s print info ...",
                                     std::to_string(i));
        }
        // 这部分证明：RCLCPP_XXX_THROTTLE的使用和这个宏的使用时的位置有关，即使这个宏在一个函数中，这个函数在不同的地方被调用了，
        // 因为这个宏被使用的地方就只有一个，所以所有所有函数中的这个宏都惠相互值越
      }
      // for (size_t i = 0; i < 3; ++i)
      // {
      //     // single_clcok_[i]->throttle(this->get_logger(),
      //     *this->get_clock(), 10000, "clock %s print info ...",
      //     std::to_string(i)); if (i == 0)
      //     {
      //         RCLCPP_INFO_THROTTLE(this->get_logger(), *this->get_clock(),
      //         10000, "clock %d print info ...", 1);
      //     }
      //     else if (i == 1)
      //     {
      //         RCLCPP_INFO_THROTTLE(this->get_logger(), *this->get_clock(),
      //         5000, "clock %d print info ...", 2);
      //     }
      //     else
      //     {
      //         RCLCPP_INFO_THROTTLE(this->get_logger(), *this->get_clock(),
      //         1000, "clock %d print info ...", 3);
      //     }
      // }
    }
  }

private:
  std::vector<std::shared_ptr<singleClock>> single_clcok_;
};

int main(int argc, char **argv) {
  rclcpp::init(argc, argv);
  auto node = std::make_shared<NodeLog>("multiple_rclcpp_throttle");
  node->timer_out();
  // rclcpp::spin(node);
  // rclcpp::shutdown();

  return 0;
}